package TankGame1;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.util.Vector;

/**
 * 面板设计
 */
public class MyPanel extends JPanel implements KeyListener, Runnable {
    private MyTank myTank; //自己的坦克
    private int initialTankCount = 8; //初始坦克数量
    private Vector<EnemyTank> EnemyTanks = new Vector<>(); //保存敌方坦克
    private Vector<Bomb> bombs = new Vector<>(); //爆炸效果
    private Recorder recorder;
    private ObjectInputStream ois;
    Image image1 = null; //爆炸图1
    Image image2 = null; //爆炸图2
    Image image3 = null; //爆炸图3

    public MyPanel(int j) throws Exception {
        myTank = new MyTank(400, 400, 0, EnemyTanks);
        if (j == 0) {
            //开始新游戏
            startNewGame();
        } else {
            //继续上一局游戏
            File file = new File(MyFrame.class.getResource("src\\main\\java\\TankGame1\\recorder1.txt").toURI());
            if (!file.exists()) {
                Object[] options = {"是", "否"};
                int res = JOptionPane.showOptionDialog(null, "当前无存档，是否开启新游戏？", "选择", JOptionPane.YES_NO_OPTION,
                        JOptionPane.QUESTION_MESSAGE, null, options, null);
                if (res == 0) {
                    startNewGame();
                } else {
                    System.exit(0);
                }
            } else {
                ois = new ObjectInputStream(new FileInputStream(file));
                Object object = ois.readObject();
                if (object != null) {
                    recorder = (Recorder) object;
                    EnemyTanks = new Vector<>(recorder.getEnemyTanks());
                    for (int i = 0; i < EnemyTanks.size(); i++) {
                        new Thread(EnemyTanks.get(i)).start();
                    }
                }
                ois.close();
            }
        }
        //读取images下图片加载爆炸图
        image1 = new ImageIcon("images/TangKeDaZhan/bomb_1.png").getImage();
        image2 = new ImageIcon("images/TangKeDaZhan/bomb_2.png").getImage();
        image3 = new ImageIcon("images/TangKeDaZhan/bomb_3.png").getImage();

    }

    public void showInfo(Graphics g) {
        g.setColor(Color.black);
        Font font = new Font("楷体", Font.BOLD, 25);
        g.setFont(font);
        g.drawString("您累积击毁敌方坦克", 1020, 30);
        g.drawString(recorder.getKillNums() + "", 1080, 100);
        drawTank(1020, 60, 0, 0, g);
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        g.fillRect(0, 0, 1000, 750);
        showInfo(g);
        if (myTank.isLive())
            drawTank(myTank.getX(), myTank.getY(), 0, myTank.getDirection(), g);
        Vector<Shot> shotsVector = myTank.getShots(); //己方子弹库
        for (int i = 0; i < shotsVector.size(); i++) {
            Shot shot = shotsVector.get(i);
            g.fill3DRect(shot.getX(), shot.getY(), 3, 3, false);
        }
        for (int i = 0; i < bombs.size(); i++) {
            Bomb bomb = bombs.get(i);
            if (bomb.getLife() > 12) {
                g.drawImage(image1, bomb.getX(), bomb.getY(), 60, 60, this);
            } else if (bomb.getLife() > 6) {
                g.drawImage(image2, bomb.getX(), bomb.getY(), 60, 60, this);
            } else {
                g.drawImage(image3, bomb.getX(), bomb.getY(), 60, 60, this);
            }
            bomb.lifeDown(); //炸弹效果
            if (!bomb.isLive()) {
                bombs.remove(bomb);
                i--;
            }
        }
        for (int i = 0; i < EnemyTanks.size(); i++) {
            EnemyTank tank = EnemyTanks.get(i);
            if (tank.isLive()) { //敌人坦克还活着就要画
                drawTank(tank.getX(), tank.getY(), 1, tank.getDirection(), g);
            }
            for (int j = 0; j < tank.getShots().size(); j++) { //查看敌人发射子弹情况
                Shot shot = tank.getShots().get(j); //得到子弹之一
                g.setColor(Color.yellow);
                g.draw3DRect(shot.getX(), shot.getY(), 3, 3, false);
            }
            if (tank.getShots().size() == 0 && !tank.isLive()) { //坦克当前被消灭且子弹生命期都结束
                EnemyTanks.remove(tank);
                i--;
            }
        }
    }

    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //遍历敌人坦克，看看子弹能不能打到
            for (int i = 0; i < EnemyTanks.size(); i++) {
                EnemyTank enemyTank = EnemyTanks.get(i); //敌人坦克
                shotsTank(myTank.getShots(), enemyTank);//我打敌人
                shotsTank(enemyTank.getShots(), myTank);//敌人打我
            }
            repaint();
        }
    }

    /**
     * @param shot1 对方子弹
     * @param tank  坦克
     */
    public boolean hitTank(Shot shot1, TankModel tank) {
        int direction = tank.getDirection(); //坦克方向
        int x = shot1.getX();
        int y = shot1.getY();
        int tankX = tank.getX();
        int tankY = tank.getY();
        switch (direction) {
            case 0://上
            case 2:
                if (x > tankX && x < tankX + 40 && y > tankY && y < tankY + 60) {
                    //击中坦克
                    tank.setLive(false);
                    Bomb bomb = new Bomb(tank.getX(), tank.getY());//在被子弹击中处设置一个爆炸效果
                    bombs.add(bomb);
                    return true;
                }
                break;
            case 1:
            case 3:
                if (x > tankX && x < tankX + 60 && y > tankY && y < tankY + 40) {
                    //击中坦克
                    tank.setLive(false);
                    Bomb bomb = new Bomb(tank.getX(), tank.getY());
                    bombs.add(bomb);
                    return true;
                }
                break;
        }
        return false;
    }

    /**
     * 子弹集合是否打得到目标坦克
     *
     * @param shots 子弹集合
     * @param tank  目标坦克
     */
    public void shotsTank(Vector<Shot> shots, TankModel tank) {
        for (int j = 0; j < shots.size(); j++) {
            Shot shot = shots.get(j);
            if (tank.isLive()) { //坦克活着才有被打的机会
                if (shot.isLive()) { //子弹活着
                    boolean flag = hitTank(shot, tank);
                    if (flag) { //子弹命中坦克
                        shots.remove(shot);
                        if (tank instanceof EnemyTank) {
                            recorder.setKillNums(recorder.getKillNums() + 1);
                        }
                        j--;
                    }
                } else {
                    shots.remove(shot);
                    j--;
                }
            } else {
                if (!shot.isLive())
                    shots.remove(shot);
                    j--;
                }
                break;
            }
        }


    /**
     * 绘制坦克方法
     *
     * @param x         坦克左上角x坐标
     * @param y         坦克左上角y坐标
     * @param type      //0为己方坦克，1为对方坦克
     * @param direction //方向，0上,1右,2下,3左
     * @param g         //画笔
     */
    public void drawTank(int x, int y, int type, int direction, Graphics g) {
        //设置坦克颜色
        switch (type) {
            case 0:
                g.setColor(Color.cyan);
                break;
            case 1:
                g.setColor(Color.yellow);
                break;
        }
        //根据方向进行绘制
        switch (direction) {
            case 0:
            case 2:
                g.fill3DRect(x, y, 10, 60, false);
                g.fill3DRect(x + 10, y + 10, 20, 40, false);
                g.fill3DRect(x + 30, y, 10, 60, false);
                g.fillOval(x + 10, y + 20, 20, 20);
                if (direction == 0) {
                    g.drawLine(x + 20, y, x + 20, y + 30);//炮筒
                } else {
                    g.drawLine(x + 20, y + 60, x + 20, y + 30);
                }
                break;
            case 1:
            case 3:
                g.fill3DRect(x, y, 60, 10, false);
                g.fill3DRect(x + 10, y + 10, 40, 20, false);
                g.fill3DRect(x, y + 30, 60, 10, false);
                g.fillOval(x + 20, y + 10, 20, 20);
                if (direction == 1) {
                    g.drawLine(x + 30, y + 20, x + 60, y + 20);
                } else {
                    g.drawLine(x + 30, y + 20, x, y + 20);
                }
                break;
        }
    }

    public void startNewGame() {
        for (int i = 0; i < initialTankCount; i++) {
            EnemyTank enemyTank = new EnemyTank(100 * (i + 1), 10, 2, EnemyTanks, myTank);
            EnemyTanks.add(enemyTank); //将坦克加入数组中
            new Thread(enemyTank).start();
        }
        recorder = new Recorder();
        recorder.setEnemyTanks(EnemyTanks);
    }

    @Override
    public void keyPressed(KeyEvent e) {

        switch (e.getKeyCode()) {
            case 87:
                //W键
                myTank.setDirection(0);
                myTank.setY(myTank.getY() - 10);
                repaint();
                break;
            case 83:
                //S键
                myTank.setDirection(2);
                myTank.setY(myTank.getY() + 10);
                repaint();
                break;
            case 65:
                //A键
                myTank.setDirection(3);
                myTank.setX(myTank.getX() - 10);
                repaint();
                break;
            case 68:
                //D键
                myTank.setDirection(1);
                myTank.setX(myTank.getX() + 10);
                repaint();
                break;
            case 74:
                //J键
                if (myTank.getShots().size() < 5 && myTank.isLive())
                    myTank.Shooting();
                break;
        }
    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyReleased(KeyEvent e) {

    }

    public Recorder getRecorder() {
        return recorder;
    }

    public Vector<EnemyTank> getEnemyTanks() {
        return EnemyTanks;
    }
}
